package rjeutsky.database.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;

import rjeutsky.database.interfaces.CRUDDomainRepository;
import rjeutsky.models.User;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;

public class UserDomainRepository implements CRUDDomainRepository<User> {

	private static final String CREATE_SQL = "INSERT INTO User (Id, Login, Password, Salt) VALUES (?, ?, ?, ?)";
	private static final String CREATE_SQL_NO_ID = "INSERT INTO User (Login, Password, Salt) VALUES (?, ?, ?)";
	private static final String QUERY_SQL = "SELECT Id, Login, Password, Salt FROM User";
	private static final String READ_SQL = "SELECT Id, Login, Password, Salt FROM User WHERE Id = ?";
	
	private PreparedStatement createStatement;
	private PreparedStatement createStatementNoId;
	private PreparedStatement queryStatement;
	private PreparedStatement readStatement;
	
	
	public UserDomainRepository(Connection connection) throws SQLException {
		createStatement = connection.prepareStatement(CREATE_SQL, PreparedStatement.RETURN_GENERATED_KEYS);
		createStatementNoId = connection.prepareStatement(CREATE_SQL_NO_ID, PreparedStatement.RETURN_GENERATED_KEYS);
		queryStatement = connection.prepareStatement(QUERY_SQL);
		readStatement = connection.prepareStatement(READ_SQL);
	}
	
	@Override
	public void create(User item) throws SQLException {
		if (item.getId() == null) {
			createStatementNoId.setString(1, item.getLogin());
			createStatementNoId.setString(2, item.getPassword());
			createStatementNoId.setString(3, item.getSalt());
			createStatementNoId.executeUpdate();
			ResultSet generatedKeys = createStatementNoId.getGeneratedKeys();
			generatedKeys.next();
			item.setId(generatedKeys.getLong(1));
		}
		else {
			createStatement.setLong(1, item.getId());
			createStatement.setString(2, item.getLogin());
			createStatement.setString(3, item.getPassword());
			createStatement.setString(4, item.getSalt());
			createStatement.executeUpdate();
		}
	}

	@Override
	public void delete(long id) {
		// TODO Auto-generated method stub
		throw new NotImplementedException();
	}

	@Override
	public User read(long id) throws SQLException {
		readStatement.setLong(1, id);
		ResultSet resultSet = readStatement.executeQuery();
		while (resultSet.next()) {
			User user = new User();
			user.setId(resultSet.getLong(1));
			user.setLogin(resultSet.getString(2));
			user.setPassword(resultSet.getString(3));
			user.setSalt(resultSet.getString(4));
			return user;
		}
		
		return null;
	}

	@Override
	public void update(User item) {
		// TODO Auto-generated method stub
		throw new NotImplementedException();
	}

	@Override
	public List<User> query() throws SQLException {
		List<User> users = new LinkedList<User>();
		ResultSet resultSet = queryStatement.executeQuery();
		while (resultSet.next()) {
			User user = new User();
			user.setId(resultSet.getLong(1));
			user.setLogin(resultSet.getString(2));
			user.setPassword(resultSet.getString(3));
			user.setSalt(resultSet.getString(4));
			users.add(user);
		}
		
		return users;
	}

}
